import { Commit, createStore } from 'vuex'
import axios from 'axios'
// 封装 get 请求 - Commit就是 commit 类型
const getAndCommit = async (
  url: string,
  mutationName: string,
  commit: Commit
) => {
  // commit('setLoading', true) // 开始
  const { data } = await axios.get(url)
  commit(mutationName, data)
  // await new Promise(resolve => setTimeout(resolve, 3000))
  // commit('setLoading', false) // 结束
}

// 封装 post 请求
const postAndCommit = async (
  url: string,
  mutationName: string,
  commit: Commit,
  payload: any
) => {
  const { data } = await axios.post(url, payload)
  commit(mutationName, data)
}
// import { testData, testProps, ColumnProps, PostProps } from '@/testData' // 得使用我们数据

export interface UserProps {
  // 当前是否登录
  isLogin: boolean
  nickName?: string
  _id?: string
  columnId?: number // 用户自己的专栏 ID
}
// 图片的描述
export interface ImageProps {
  _id?: string
  url?: string
  createdAt?: string
}

export interface ColumnProps {
  // 专栏列表
  _id: string
  title: string // 标题
  avatar?: ImageProps // 头像
  description: string // 描述
}
export interface PostProps {
  // 文章列表
  _id: string
  title: string
  excerpt?: string
  content?: string // 内容
  image?: ImageProps // 图片
  createdAt: string // 发布时间
  column: string // 文章 Id，因为你点开的那个文章要和你的文章 ID 做匹配
}
// 声明错误
export interface GlobalErrorProps {
  status: boolean,
  message?: string
}
// 如果你想在其他页面使用的话导出就可以了
export interface GolbalDataProps {
  columns: ColumnProps[]
  posts: PostProps[]
  user: UserProps
  loading: boolean
  token: string
  error: GlobalErrorProps
}

const store = createStore<GolbalDataProps>({
  state: {
    columns: [],
    posts: [],
    user: { isLogin: false },
    loading: false,
    token: localStorage.getItem('token') || '',
    error: { status: false }
  },
  // Vuex 允许我们在 store 中定义 'getter' (可以认为是 store 的计算属性)
  // getter 的返回值会根据它的依赖被缓存起来，且只有当他的依赖值发生了改变才会被重新计算
  getters: {
    // 定义完毕了，就可以在应用中使用这个 getter 了
    // Getter 会暴露为 store.getters 对象
    // biggerColumnsLen (state) {
    //   return state.columns.filter(c => c._id > 2).length
    // },
    // 当前跳转的专栏详情是否是我点击的专栏
    // 专栏详情
    getColumnById: (state) => (id: string) => {
      return state.columns.find((c) => c._id === id)
    },
    // 文章列表
    getPostById: (state) => (cid: string) => {
      return state.posts.filter((post) => post.column === cid)
    }
  },
  mutations: {
    // 登录
    login (state, rawData) {
      // state.token = rawData.data.token
      const { token } = rawData.data
      state.token = token
      localStorage.setItem('token', token)
      axios.defaults.headers.common.Authorization = `Bearer ${token}`
      // state.user = { ...state.user, isLogin: true, nickName: '迪迦奥特曼' }
    },
    fetchCurrentUser (state, rawData) {
      state.user = { isLogin: true, ...rawData.data }
    },
    // 新建文章
    createPost (state, newPost) {
      state.posts.push(newPost)
    },
    // 专栏列表
    fetchColumns (state, rwaData) {
      state.columns = rwaData.data.list
    },
    // 专栏详情
    fetchColumn (state, rwaData) {
      state.columns = [rwaData.data]
    },
    // 文章列表
    fetchPosts (state, rwaData) {
      state.posts = rwaData.data.list
    },
    // 控制 loading 效果显示个隐藏
    setLoading (state, status) {
      state.loading = status // true 和 false 的值
    },
    setError (state, e: GlobalErrorProps) {
      state.error = e
    }
  },
  // action 类似于 mutation
  // action 提交的是 mutation ,而不是直接改变状态
  actions: {
    // 专栏列表
    async fetchColumns (context) {
      // axios.get('/columns').then(resp => {
      //   context.commit('fetchColumns', resp.data)
      // })

      // const { data } = await axios.get('/columns')
      // context.commit('fetchColumns', data)

      getAndCommit('/columns', 'fetchColumns', context.commit)
    },
    // 专栏详情
    async fetchColumn ({ commit }, cid) {
      // axios.get(`/columns/${cid}`).then(resp => {
      //   commit('fetchColumn', resp.data)
      // })

      // const { data } = await axios.get(`/columns/${cid}`)
      // commit('fetchColumn', data)

      getAndCommit(`/columns/${cid}`, 'fetchColumn', commit)
    },
    // 文章列表
    async fetchPosts ({ commit }, cid) {
      // axios.get(`/columns/${cid}/posts`).then(resp => {
      //   commit('fetchPosts', resp.data)
      // })

      // const { data } = await axios.get(`/columns/${cid}/posts`)
      // commit('fetchPosts', data)

      getAndCommit(`/columns/${cid}/posts`, 'fetchPosts', commit)
    },
    // 登录
    login ({ commit }, payload) {
      return postAndCommit('/user/login', 'login', commit, payload)
    },
    fetchCurrentUser ({ commit }) {
      getAndCommit('/user/current', 'fetchCurrentUser', commit)
    },
    loginAndFecth ({ dispatch }, loginData) {
      return dispatch('login', loginData).then(() => {
        return dispatch('fetchCurrentUser')
      })
    }
  },
  modules: {}
})

export default store
